package com.dy.aspect;

import com.dy.pojo.vo.RequestLog;
import org.aopalliance.intercept.Joinpoint;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.ServletRequestHandledEvent;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName:
 * @Author: 仄言in
 * @Desctiption: (描述)：日志记录处理
 * @Date: 2021/5/7 15:19
 * @Version 1.0 (版本)
 */
@Aspect
@Component
public class LogAspect {
    private final Logger log= LogManager.getLogger(LogAspect.class);
    /**
     * 定义切面(切点)
     * execution():规定拦截哪些类
     */
    @Pointcut("execution(* com.dy.controller.*.*(..))")
    public void log(){
    }

    /**
     * @Before：前置通知
     * JoinPoint：封装了aop切面的方法
     * 用于日志记录请求的 url，ip，方法名，请求参数对象
     */
    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        log.info("-------doBefore---------");
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url=request.getRequestURI().toString();
        String ip=request.getRemoteAddr();
        String classMethod= joinPoint.getSignature().getDeclaringTypeName()+" "+joinPoint.getSignature().getName();
        Object[] args=joinPoint.getArgs();
        RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
        log.info("RequestLog :  {}",requestLog);
    }
    /**
     * 后置通知
     */
    @After("log()")
    public void doAfter(){
        //log.info("-----------doAfter---------");
    }

    /**
     * @AfterReturning;目标方法被正常执行后,可以接收返回值
     * 记录返回的内容
     * @param result
     */
    @AfterReturning(returning = "result",pointcut = "log()")
    public void doAfterRuturn(Object result){
        log.info("Result : {}",result);
    }
}
